package com.sneakxy.cloudbase.platform.utils.fastdfs;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.csource.common.MyException;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;

import com.sneakxy.cloudbase.platform.utils.web.HttpServletResponseUtils;
import com.sneakxy.cloudbase.platform.utils.web.HttpServletResponseUtils.RangeIndex;

public class FastDfsClient implements InitializingBean {
	
	protected static final Logger LOG = LogManager.getLogger(FastDfsClient.class);
	
	private Resource configPath;

	private TrackerClient trackerClient;
	
	private String tempPath;
	
	public void setConfigPath(Resource configPath) {
		this.configPath = configPath;
	}

	public void setTempPath(String tempPath) {
		this.tempPath = tempPath;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		if(configPath != null) {
			File dir = new File(this.tempPath);
			if(!dir.exists()) {
				dir.mkdirs();
			}
			String path = StringUtils.join(tempPath, "/fdfs_config.temp");
			try(InputStream is = this.configPath.getInputStream();
				OutputStream os = new FileOutputStream(path);) {
				IOUtils.copy(is, os);
			} finally {
				ClientGlobal.init(path);
				if(!Files.deleteIfExists(Paths.get(path))) {
					//日志
					LOG.warn("临时文件未成功删除.");
				}
			}
		} else {
			ClientGlobal.init(this.getClass().getClassLoader().getResource("fdfs_client.conf").getFile());
		}
		trackerClient = new TrackerClient();
	}
	
	public int deleteFile(String fileId) throws IOException, MyException {
		TrackerServer trackerServer = null;
		StorageServer storageServer = null;
		StorageClient2 storageClient2 = null;
		try {
			trackerServer = trackerClient.getConnection();
			storageServer = trackerClient.getStoreStorage(trackerServer);
			storageClient2 = new StorageClient2(trackerServer, storageServer);
			return storageClient2.delete_file1(fileId);
		} finally {
			if(storageServer != null) {
				storageServer.close();
			}
			if(trackerServer != null) {
				trackerServer.close();
			}
		}
	}
	
	public int downloadFile(String fileId, OutputStream out) throws IOException, MyException {
		TrackerServer trackerServer = null;
		StorageServer storageServer = null;
		StorageClient2 storageClient2 = null;
		try {
			trackerServer = trackerClient.getConnection();
			storageServer = trackerClient.getStoreStorage(trackerServer);
			storageClient2 = new StorageClient2(trackerServer, storageServer);
			return storageClient2.downloadFile2(fileId, out);
		} finally {
			if(storageServer != null) {
				storageServer.close();
			}
			if(trackerServer != null) {
				trackerServer.close();
			}
		}
	}
	
	public void downloadFile(HttpServletRequest request, HttpServletResponse response, String fileId, long fileLength) throws IOException, MyException {
		TrackerServer trackerServer = null;
		StorageServer storageServer = null;
		StorageClient2 storageClient2 = null;
		try (OutputStream os = response.getOutputStream()) {
			trackerServer = trackerClient.getConnection();
			storageServer = trackerClient.getStoreStorage(trackerServer);
			storageClient2 = new StorageClient2(trackerServer, storageServer);
			//分块信息
			HttpServletResponseUtils.RangeIndice indice =  HttpServletResponseUtils.createRangeIndice(request, response, fileLength);
			for(RangeIndex index: indice.getIndice()) {
				storageClient2.downloadFile2(fileId, index.getStart(), index.length(), os);
			}
		} finally {
			if(storageServer != null) {
				storageServer.close();
			}
			if(trackerServer != null) {
				trackerServer.close();
			}
		}
	}
	
	public String uploadFile(String groupName, InputStream is, long fileSize, String fileExtName) throws IOException, MyException {
		TrackerServer trackerServer = null;
		StorageServer storageServer = null;
		StorageClient2 storageClient2 = null;
		try {
			trackerServer = trackerClient.getConnection();
			storageServer = trackerClient.getStoreStorage(trackerServer);
			storageClient2 = new StorageClient2(trackerServer, storageServer);
			return storageClient2.uploadFile2(groupName, is, fileSize, fileExtName, null);
		} finally {
			if(storageServer != null) {
				storageServer.close();
			}
			if(trackerServer != null) {
				trackerServer.close();
			}
		}
	}
	
	public String uploadFile(InputStream is, long fileSize, String fileExtName) throws IOException, MyException {
		TrackerServer trackerServer = null;
		StorageServer storageServer = null;
		StorageClient2 storageClient2 = null;
		try {
			trackerServer = trackerClient.getConnection();
			storageServer = trackerClient.getStoreStorage(trackerServer);
			storageClient2 = new StorageClient2(trackerServer, storageServer);
			return storageClient2.uploadFile2(is, fileSize, fileExtName, null);
		} finally {
			if(storageServer != null) {
				storageServer.close();
			}
			if(trackerServer != null) {
				trackerServer.close();
			}
		}
	}
	
}
